package cn.bbs.ba.Timer;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TimerTask;

import javax.servlet.ServletContext;

import org.apache.commons.lang.StringUtils;

import cn.bbs.ba.base.BaseDto;
import cn.bbs.ba.factory.BABeanFactory;
import cn.bbs.ba.format.ZZZFormat;
import cn.bbs.ba.html.ZPaiConstant;
import cn.bbs.ba.html.ZPaiInit;
import cn.bbs.ba.log.LogTrac;
import cn.bbs.ba.util.BASort;
import cn.bbs.ba.util.CommonUntil;
import cn.com.zzz.dao.PPJFDao;
import cn.com.zzz.dao.PkJFFlowDao;
import cn.com.zzz.pk.dto.PkJF;
import cn.com.zzz.pk.dto.PkJFFlow;
import cn.com.zzz.pk.dto.PkPepole;
import cn.com.zzz.pk.dto.PkTable;
import cn.com.zzz.pk.game.Poker;
import cn.com.zzz.pk.game.pokerhand.assist.RecogniseHand;

public class MiaoAction extends TimerTask {
	// 
	private static final int C_SCHEDULE_HOUR = 0;
	private static boolean isRunning = false;
	private ServletContext context = null;

	public MiaoAction() {
	}

	public MiaoAction(ServletContext context) {
		this.context = context;
	}

	public void run() {
		Calendar cal = Calendar.getInstance();
		if (!isRunning) {
			isRunning = true;
			try {
				if (ZPaiInit.getTable() == null) {
					isRunning = false;
					return;
				}
				PPJFDao jfDao = (PPJFDao)BABeanFactory.getBean("JF");
				PkJFFlowDao jfFlowDao = (PkJFFlowDao)BABeanFactory.getBean("JFFLOW");
				
				// 循环所有的桌子
				Iterator iterator2= ZPaiInit.getTable().entrySet().iterator(); 
		    	List<BaseDto> retList = new ArrayList<BaseDto>();
		    	PkTable table = null;
		    	while(iterator2.hasNext()){  
		    		Map.Entry  entry= (Map.Entry)iterator2.next(); 
		    		table = (PkTable)entry.getValue();
	    			// 取出用户
	    			List<PkPepole> peopleList = (List<PkPepole>)table.getValue("people");
	    			
		    		// 正在打牌中
		    		if("1".equals(table.getStt())) {
		    			// 判断用户是不是在出牌。
		    			for(int i = 0; i < peopleList.size(); i++) {
		    				PkPepole people = peopleList.get(i);
		    				// 押注中并且等待押注时间是0的时候
		    				if(people.getStt().equals("2")) {
		    					// 没有等待时间了
		    					if(people.getDdTime().equals("0")) {
		    						// 当前选手做弃牌处理
		    						people.setStt("3");
		    						nextOut(table, people.getAtWhere());
		    					}
			    				else {
			    					// 等待时间减少一秒
			    					people.setDdTime(CommonUntil.subtract(people.getDdTime(), "1"));
			    					break;
			    				}
		    				}
		    			}
		    		}
		    		// **************等待打牌 并且两个人以上（包含两个人）*****************
		    		else if("0".equals(table.getStt()) && peopleList.size() > 1) {
		    			
		    			int iStartUser = 0;
		    			// 判断是不是有两个以上的用户点击开始了
		    			for(int i = 0; i < peopleList.size(); i++) {
		    				PkPepole people = peopleList.get(i);
		    				// 等待游戏开始 并且等待时间为0
		    				if ("9".equals(people.getStt()) && people.getDdTime().equals("0")) {
		    					iStartUser ++;
		    				}
		    				// 等待游戏开始
		    				else if ("9".equals(people.getStt())){
		    					// 等待时间减一秒
		    					people.setDdTime(CommonUntil.objToString(CommonUntil.objToint(people.getDdTime()) - 1));
		    				}
		    			}
		    			
		    			// 有两个人喊开始了,游戏要设定为开始了。
		    			if(iStartUser >= 2) {
		    				
	    					// 取出每次玩游戏扣除钱数
	    					String money = ZPaiInit.getCodeMap().get("PK005").get(0).getCvalue();
	    					table.setValue("maxAmt", money);
		    				// 打牌中
		    				table.setStt("1");
		    				// 生成一副扑克
		    				Poker pk = new Poker();
		    				pk.inflater();
		    				// 放入内存
		    				ZPaiInit.TABLE_POKE.put(table.getTableId(), pk);
		    				String strStartUser = "";
			    			for(int i = 0; i < peopleList.size(); i++) {
			    				PkPepole people = peopleList.get(i);
			    				// 等待游戏开始
			    				if ("9".equals(people.getStt())){
			    					// 如果带入的钱还不够交保护费的就直接退出 游戏开始不带玩的
			    					if(CommonUntil.compare(people.getInMoney(), money) < 0)  {
			    						people.setStt("0");
			    						continue;
			    					}
			    					
			    					// 设定为开始
			    					people.setStt("1");
			    					people.setDdTime("0");
	
			    					// 不管玩不玩都要先支付一笔钱
			    					people.setInMoney(CommonUntil.subtract(people.getInMoney(), money));
			    					// 必须押注的钱数
			    					people.setOutMoney(money);
			    					// 生产两张牌
			    					people.setNowPK(pk.push()+ "," + pk.push());
			    					// 当局开始游戏的人
			    					strStartUser = strStartUser + people.getUserNo() + ",";
			    					
			    					// 当前桌子总钱数
			    					table.setValue("dqjezh", CommonUntil.add(table.getString("dqjezh"), money));
			    				}
			    			}
			    			strStartUser = strStartUser.substring(0, strStartUser.length() -1);
			    			// 当前游戏中人数
			    			table.setValue("nowUser", strStartUser);
			    			// 当前轮数
			    			table.setValue("nowLS", "1");
			    			// 得到庄家ID
			    			String userId = getZhuang(strStartUser.split(","));
			    			
			    			for(int i = 0; i < peopleList.size(); i++) {
			    				PkPepole people = peopleList.get(i);
			    				// 如果是庄家
			    				if (people.getUserNo().equals(userId)){
			    					// 押注中：2
			    					people.setStt("2");
			    					// 是庄家
			    					people.setValue("ISZHUANG", "1");
			    					String ddTime = ZPaiInit.getCodeMap().get("PK006").get(0).getCvalue();
			    					people.setDdTime(ddTime);
			    					break;
			    				}
			    			}
		    			}
		    		// 结牌中...
		    		} else if (table.getStt().equals("2")) {
		    			// 休息时间还没有到5秒
		    			if(!"0".equals(table.getString("dddpsj"))) {
		    				// 减去1秒
		    				table.setValue("dddpsj", CommonUntil.subtract(table.getString("dddpsj"), "1"));
		    			}
		    			else {
		    				String maxMoney = ZPaiInit.getCodeMap().get("PK005").get(0).getCvalue();
		    				// 0：等待打牌
		    				table.setStt("0");
		    				// 当前最大金额
		    				table.setValue("maxAmt", maxMoney);
		    				// 当前轮数
		    				table.setValue("nowLS", "0");
		    				// 公共牌
		    				table.setValue("ggPK", "");
		    				// 当前金额总和
		    				table.setValue("dqjezh", "0");
		    				
		    				List<PkPepole> pepoleListByO = (List<PkPepole>)table.getValue("people");
		    				PkPepole peopleByo = null;
		    				for (int i = 0; i < pepoleListByO.size(); i++) {
		    					peopleByo = pepoleListByO.get(i);
		    					// 等待点击开始游戏:0 
		    					peopleByo.setStt("0");
		    					// 押注钱数
		    					peopleByo.setOutMoney("0");
		    					// 手里的两张牌
		    					peopleByo.setNowPK("");
		    					// 等待时间
		    					peopleByo.setDdTime("");
		    				}
		    			}
		    		}
		    	}
			
			} catch (Exception ex) {
				ex.toString();
			}
			
			isRunning = false;
			LogTrac.trace("MiaoAction END.....");
			// }
		} else {
			LogTrac.trace("MiaoAction RUNGING.....");
		}
	}
	
	/**
	 * 等待开始
	 * @param base
	 */
	private void dengDaiStart(PkTable base) {
		List<PkPepole> pepoleList = (List<PkPepole>)base.getValue("people");
		PkPepole people = null;
		for (int i = 0; i < pepoleList.size(); i++) {
			people = pepoleList.get(i);
		}
	}
	
	/**
	 * 得到庄家
	 * @return
	 */
	public static String getZhuang(String[] strUserArr) {
		Random random = new Random();
		return strUserArr[random.nextInt(strUserArr.length)];
	}
	
	/**
	 * 结牌
	 * @param table
	 */
	public static void jiepai(PkTable table) {
		// 2：结牌中
		table.setStt("2");
		Poker pk =  ZPaiInit.TABLE_POKE.get(table.getTableId());
		// 确认牌是否够，如果不够怎么做。
		for (int i = 1; i < 6; i ++) {
			if (table.getString("ggPK").split(",").length == 5) {
				break;
			}
			if(table.getString("ggPK").equals("")) {
				table.setValue("ggPK", pk.push());
			}
			table.setValue("ggPK", table.getValue("ggPK") + "," + pk.push());
		}
		// 取出用户
		List<PkPepole> peopleList = (List<PkPepole>)table.getValue("people");
		RecogniseHand hand = null;
		List<BaseDto> yingjialist = new ArrayList<BaseDto>();
		BaseDto whoWin = null;
		PkPepole peopleZj = null; 
		// 把所有的用户都值为开始。
		for(int i = 0; i < peopleList.size(); i++) {
			whoWin = new BaseDto();
			PkPepole people = peopleList.get(i);
			// 等待点击开始游戏:0 
			// 等待中游戏已经开始:9 
			if ("0".equals(people.getStt()) 
					|| "9".equals(people.getStt())) {
				continue;
			}
			PPJFDao jfDao = (PPJFDao)BABeanFactory.getBean("JF");
			PkJF jf = new PkJF();
			jf.setUserNo(people.getUserNo());
			jf = jfDao.getJF(jf, "0").get(0);
			// 当前积分+剩余积分
			jf.setDqfs(CommonUntil.add(jf.getDqfs(), people.getInMoney()));
			// 更新当前积分
			jfDao.updateJF(jf);
			
			hand = new RecogniseHand();
			hand.addCardSerial(table.getValue("ggPK") + "," + people.getNowPK());
			hand.recognise();
			// 只有没有退出的用户才可以做赢牌处理
			//押注中：2--显示押注按钮
			//全押：5
			// 等待押注:1(都弃牌)
			if ("1".equals(people.getStt())
					|| "2".equals(people.getStt()) 
					|| "5".equals(people.getStt())) {
				whoWin.setValue("userNo", people.getUserNo());
				whoWin.setValue("levelName", hand.maxPokerHand().pokerHandName());
				whoWin.setValue("level", hand.maxPokerHand().pokerHandType());
				yingjialist.add(whoWin);
			}
			// 当前人为庄家
			if(people.getStt().equals("1")) {
				peopleZj = people;
			}
		}
		String[][] pkeys = {{"LEVEL","1"}};
		BASort sort = new BASort(pkeys);
		// 根据赢家排序
		Collections.sort(yingjialist, sort);
		
		// 算边池
		List<BaseDto> bianchiList = new ArrayList<BaseDto>();
		// 非空
		if(table.getValue("bianchi") != null 
				&& !"".equals(table.getValue("bianchi"))) {
			bianchiList = (List<BaseDto>)table.getValue("bianchi");
		}

		// 真正赢钱的人
		List<BaseDto> ypList = new ArrayList<BaseDto>();
		for(int i = 0; i < bianchiList.size(); i ++) {
			BaseDto yingPairen = new BaseDto();
			// 边池
			BaseDto bianchi = bianchiList.get(i);
			// 第一个边池 并且他的牌最大则给他分边池。
			if(yingjialist.get(0).getString("userNo").equals(bianchi.getString("userNo"))) {
				
				PPJFDao jfDao = (PPJFDao)BABeanFactory.getBean("JF");
				PkJF jf = new PkJF();
				jf.setUserNo(bianchi.getString("userNo"));
				jf = jfDao.getJF(jf, "0").get(0);
				String baifenbi = CommonUntil.subtract("100", ZPaiInit.getCodeMap().get("PK006").get(0).getCvalue());
				// *****************************手续费*********************
				// 计入流水
				PkJFFlowDao jfFlow = (PkJFFlowDao)BABeanFactory.getBean("JFFLOW");
				PkJFFlow flDtoSxf = new PkJFFlow();
				
				flDtoSxf.setFlowNo(ZZZFormat.getSysteTime());
				// 管理员
				flDtoSxf.setUserNo("999999999");
				// 手续费
				flDtoSxf.setXfjf(CommonUntil.divide(CommonUntil.multiply(bianchi.getString("money"),
						ZPaiInit.getCodeMap().get("PK006").get(0).getCvalue()), "100"));
				flDtoSxf.setFjNo(table.getRoomId());
				flDtoSxf.setZzNo(table.getTableId());
				flDtoSxf.setPkVa(yingjialist.get(0).getString("userNo"));
				flDtoSxf.setExDate(ZZZFormat.getTime());
				// 流水
				flDtoSxf.setEx1("9");
				flDtoSxf.setRemarks(ZPaiConstant.disPlay("手续费"));
				
				jfFlow.insertJF(flDtoSxf);
				//*******************************************
				String strYue = CommonUntil.divide(CommonUntil.multiply(bianchi.getString("money"), baifenbi), "100");
				
				// 把积分 加进去
				for(int m = 0; m < peopleList.size(); m++) {
					PkPepole peoplem = peopleList.get(m);
					if (peoplem.getUserNo().equals(bianchi.getString("userNo"))) {
						peoplem.setInMoney(strYue);
					}
				}	
				// 当前积分+赢取积分
				jf.setDqfs(CommonUntil.add(jf.getDqfs(), strYue));
				// 更新当前积分
				jfDao.updateJF(jf);
				
				// 计入流水
				PkJFFlow flDto = new PkJFFlow();
				
				flDto.setFlowNo(ZZZFormat.getSysteTime());
				flDto.setUserNo(bianchi.getString("userNo"));
				flDto.setXfjf(strYue);
				flDto.setFjNo(table.getRoomId());
				flDto.setZzNo(table.getTableId());
				flDto.setPkVa("");
				flDto.setExDate(ZZZFormat.getTime());
				// 流水
				flDto.setEx1("9");
				flDto.setRemarks(ZPaiConstant.disPlay("赢牌计入流水"));
				
				jfFlow.insertJF(flDto);
				// 当前积分递减
				table.setValue("dqjezh", CommonUntil.subtract(table.getString("dqjezh"), bianchi.getString("money")));
				// 赢钱的人
				yingPairen.setValue("userNo", bianchi.getString("userNo"));
				yingPairen.setValue("bieming", bianchi.getString("bieming"));
				yingPairen.setValue("yqName", yingjialist.get(0).getValue("levelName"));
				yingPairen.setValue("money", strYue);
				ypList.add(yingPairen);
				// 把赢牌的人给搞掉
				yingjialist.remove(0);
			}
			
		}
		// 现在还有钱，最后庄家
		if (CommonUntil.objToint(table.getString("dqjezh")) > 0) {
			
			
			PPJFDao jfDao = (PPJFDao)BABeanFactory.getBean("JF");
			PkJF jf = new PkJF();
			jf.setUserNo(peopleZj.getUserNo());
			jf = jfDao.getJF(jf, "0").get(0);
			String baifenbi = CommonUntil.subtract("100", ZPaiInit.getCodeMap().get("PK006").get(0).getCvalue());
			String strYue = CommonUntil.divide(CommonUntil.multiply(table.getString("dqjezh"), baifenbi), "100");
			
			// *****************************手续费*********************
			// 计入流水
			PkJFFlowDao jfFlow = (PkJFFlowDao)BABeanFactory.getBean("JFFLOW");
			PkJFFlow flDtoSxf = new PkJFFlow();
			
			flDtoSxf.setFlowNo(ZZZFormat.getSysteTime());
			// 管理员
			flDtoSxf.setUserNo("999999999");
			// 手续费
			flDtoSxf.setXfjf(CommonUntil.divide(CommonUntil.multiply(table.getString("dqjezh"),
					ZPaiInit.getCodeMap().get("PK006").get(0).getCvalue()), "100"));
			flDtoSxf.setFjNo(table.getRoomId());
			flDtoSxf.setZzNo(table.getTableId());
			flDtoSxf.setPkVa(yingjialist.get(0).getString("userNo"));
			flDtoSxf.setExDate(ZZZFormat.getTime());
			// 流水
			flDtoSxf.setEx1("9");
			flDtoSxf.setRemarks(ZPaiConstant.disPlay("手续费"));
			
			jfFlow.insertJF(flDtoSxf);
			
			//*******************************************
			
			// 把积分 加进去
			for(int m = 0; m < peopleList.size(); m++) {
				PkPepole peoplem = peopleList.get(m);
				if (peoplem.getUserNo().equals(peopleZj.getUserNo())) {
					peoplem.setInMoney(CommonUntil.add(peoplem.getInMoney(), strYue));
				}
			}	
			
			// 当前积分+赢取积分
			jf.setDqfs(CommonUntil.add(jf.getDqfs(), strYue));
			// 更新当前积分
			jfDao.updateJF(jf);
			
			// 计入流水
			PkJFFlow flDto = new PkJFFlow();
			
			flDto.setFlowNo(ZZZFormat.getSysteTime());
			flDto.setUserNo(peopleZj.getUserNo());
			flDto.setXfjf(strYue);
			flDto.setFjNo(table.getRoomId());
			flDto.setZzNo(table.getTableId());
			flDto.setPkVa("");
			flDto.setExDate(ZZZFormat.getTime());
			// 流水
			flDto.setEx1("9");
			flDto.setRemarks(ZPaiConstant.disPlay("赢牌计入流水"));
			
			jfFlow.insertJF(flDto);
			// 当前积分递减
			table.setValue("dqjezh", CommonUntil.subtract(table.getString("dqjezh"), table.getString("dqjezh")));
			BaseDto yingPairen = new BaseDto();
			// 赢钱的人
			yingPairen.setValue("userNo", peopleZj.getUserNo());
			yingPairen.setValue("bieming", peopleZj.getAlias());
			yingPairen.setValue("yqName", yingjialist.get(0).getValue("levelName"));
			yingPairen.setValue("money", strYue);
			ypList.add(yingPairen);
			// 把赢牌的人给搞掉
			yingjialist.remove(0);
		}
		
		// 真正赢钱的人
		table.setValue("yingpai", ypList);
		String maxMoney = ZPaiInit.getCodeMap().get("PK005").get(0).getCvalue();
		table.setValue("maxAmt", maxMoney);
		// 0：等待打牌
		// table.setStt("0");
		// 设定等待打牌时间
		table.setValue("dddpsj", "10");
		// 如果有人退出游戏 结牌的时候把此人清空
		if (StringUtils.isNotEmpty(table.getString("outUserNo"))) {
			String[] outUserNo = StringUtils.split(table.getString("outUserNo"), ",");
			for (int v = 0; v < outUserNo.length; v ++) {
				
				for(int i = 0; i < peopleList.size(); i++) {
					// 如果相等退出 情况table
					if (peopleList.get(i).getUserNo().equals(outUserNo[v])) {
						peopleList.remove(i);
						break;
					}
				}
			}
		}
		
	}
	/**
	 * 查找下一个出牌者
	 * @param zhuoziDto
	 * @param arWhere
	 */
	public static void nextOut(PkTable zhuoziDto, String arWhere) {
		
		List<PkPepole> peopleList = (List<PkPepole> )zhuoziDto.getValue("people");
		int nowAtWhere = CommonUntil.objToint(arWhere);
		// 开始位置
		int start = nowAtWhere + 1;
		
		// 如果在第八个桌子坐着下个肯定是1押钱
		if (start > 8) {
			start = 1;
		}
		boolean zhaodao = false;
		// 无线循环自动退出
		while(true) {
			int i当前打牌人数 = 0;
			for(int j = 0; j < peopleList.size(); j++) {
				PkPepole peopleNow = peopleList.get(j);
				// 有人 等待押注:1 押注中：2 全押：5
				if ("1".equals(peopleNow.getStt())
						|| "2".equals(peopleNow.getStt())) {
					i当前打牌人数 ++;
				}
				
			}
			// 寻找下个出牌选手
			for(int j = 0; j < peopleList.size(); j++) {
				PkPepole peopleNow = peopleList.get(j);

				// 等待押注:1 并且位置也相同
				if (peopleNow.getStt().equals("1") && 
						peopleNow.getAtWhere().equals(CommonUntil.objToString(start))) {
					zhaodao = true;
					
					// 设定等待时间
					String ddTime = ZPaiInit.getCodeMap().get("PK006").get(0).getCvalue();
					peopleNow.setDdTime(ddTime);
					// ********************是否发牌**************************
					boolean goOn = false;
					// 如果当前人是庄家，确认是第几轮了 看看是否能够发牌
					if(peopleNow.getValue("ISZHUANG").equals("1")) {
						for(int k = 0; k < peopleList.size(); k++) {
							PkPepole peopleK = peopleList.get(k);
							if (peopleK.getStt().equals("1") 
									&& peopleNow.getUserNo().equals(peopleK.getUserNo())
									&& peopleK.getOutMoney().equals(zhuoziDto.getValue("maxAmt"))) {
								goOn = true;
							}
						}
					}
					// 已经全部相同，发牌
					if (goOn) {
						Poker pk =  ZPaiInit.TABLE_POKE.get(zhuoziDto.getTableId());
						// 第一轮押注
						if(zhuoziDto.getValue("nowLS").equals("1")) {
							zhuoziDto.setValue("ggPK", pk.push());
							zhuoziDto.setValue("ggPK", zhuoziDto.getValue("ggPK") + "," + pk.push());
							zhuoziDto.setValue("ggPK", zhuoziDto.getValue("ggPK") + "," + pk.push());
							zhuoziDto.setValue("nowLS", "2");
						}
						else if(zhuoziDto.getValue("nowLS").equals("2")){
							zhuoziDto.setValue("ggPK", zhuoziDto.getValue("ggPK") + "," + pk.push());
							zhuoziDto.setValue("nowLS", "3");
						}
						else if(zhuoziDto.getValue("nowLS").equals("3")){
							zhuoziDto.setValue("ggPK", zhuoziDto.getValue("ggPK") + "," + pk.push());
							zhuoziDto.setValue("nowLS", "4");
						}
						else if(zhuoziDto.getValue("nowLS").equals("4")){
							jiepai(zhuoziDto);
						}
						
					}
					// 等待押注
					peopleNow.setStt("2");
					break;
				}

			}
			
			// 当前没有人要出牌了。
			if (i当前打牌人数 <= 1) {
				boolean next = true;
				for(int j = 0; j < peopleList.size(); j++) {
					PkPepole peopleNow = peopleList.get(j);
					// 有人 等待押注:1 
					// 押注中：2 
					// 有人全押了。
					if (("1".equals(peopleNow.getStt())
							|| "2".equals(peopleNow.getStt()))
							&& (!peopleNow.getOutMoney().equals(zhuoziDto.getString("maxAmt"))
									&& zhuoziDto.getString("nowPeopleStt").equals("5"))) {
						next = false;
					}
					
				}
				// 执行的是全押 并且金钱不通。
				if (next) {
					// 结牌
					MiaoAction.jiepai(zhuoziDto);
					break;
				}
			}
			
			// 如果找到,退出
			if (zhaodao) {
				break;
			}
			start ++;
			// 如果在第八个桌子坐着下个肯定是1押钱
			if (start > 8) {
				start = 1;
			}
		}
	}
}
